import { DrugShowModelDto, FilterRange } from '../Models/Dtos/DrugShowModelDto'
import { cloud, CloudDB, CloudDBCollection } from '@hw-agconnect/cloud-server';
import { DBUtil } from '../Methods/DBUtil'
import { TbDrug, TbDrugType, TbDrugUnit, TbUserDrug, TbDrugAndType, TbUserDrugType } from '../DBModels/DBModel'

export class DrugModelServer {
  private static ZONENAME: string = "YaoBox";

  /**
   * 添加药品
   * @param userID 用户ID
   * @param data 药品dto
   * @returns
   */
  public static async AddDrugAsync(userID: string, data: DrugShowModelDto): Promise<string> {
    const db: CloudDB = cloud.database({ zoneName: this.ZONENAME });
    //拿到所有的药品集合
    let drugs: TbDrug[] = await DBUtil.QueryEqualToAndAddAsync(TbDrug, "DrugName", data.Name, () => {
      let temp: TbDrug = new TbDrug();
      temp.DrugName = data.Name;
      return temp;
    })
    //拿到药品类型集合
    let drugTypes: TbDrugType[] = await DBUtil.QueryEqualToAndAddAsync(TbDrugType, "Name", data.DrugType, () => {
      let temp: TbDrugType = new TbDrugType();
      temp.Name = data.DrugType;
      return temp;
    })
    //拿到药品单位集合
    let units: TbDrugUnit[] = await DBUtil.QueryEqualToAndAddAsync(TbDrugUnit, "UnitName", data.DrugUnit, () => {
      let temp: TbDrugUnit = new TbDrugUnit();
      temp.UnitName = data.DrugUnit;
      return temp;
    })
    let drugModel: TbUserDrug = new TbUserDrug();
    drugModel.DrugID = drugs[0].id;
    drugModel.UserID = userID;
    drugModel.UnitID = units[0].id;
    drugModel.RemainingNumber = data.RemainingNumber;
    drugModel.CreateTime = new Date(data.CreateTime);
    drugModel.ExpirationTime = new Date(data.ExpirationDate);
    drugModel.IconPath = data.IconPath;
    await DBUtil.AddAsync(drugModel);
    let nwUserDrugs: TbUserDrug[] = await db
      .collection(TbUserDrug)
      .query()
      .equalTo("DrugID", drugs[0].id)
      .equalTo("UserID", userID)
      .orderByDesc("CreateTime")
      .get();
    let drugType: TbDrugAndType = new TbDrugAndType();
    drugType.UserDrugID = nwUserDrugs[0].id;
    drugType.DrugType = drugTypes[0].id;
    await DBUtil.AddAsync(drugType);
    return "添加成功"
  }

  /**
   * 获取当前用户的所有数据
   * @param userID
   * @returns
   */
  public static async GetDrugByUserAsync(userID: string): Promise<DrugShowModelDto[]> {
    let result: DrugShowModelDto[] = [];
    let userDrugs: TbUserDrug[] = await DBUtil.QueryEqualToAsync(TbUserDrug, "UserID", userID);
    if (userDrugs.length == 0) {
      return result;
    }
    let drugAndTypes: TbDrugAndType[] =
      await DBUtil.QueryInAsync(TbDrugAndType, "UserDrugID", userDrugs.map(x => x.id));
    let drugTypes: TbDrugType[] = await DBUtil.QueryInAsync(TbDrugType, "id", drugAndTypes.map(x => x.DrugType));
    let drugs: TbDrug[] = await DBUtil.QueryAsync(TbDrug, async m => {
      return m.in("id", userDrugs.map(x => x.DrugID))
    })
    let drugUnits: TbDrugUnit[] = await DBUtil.QueryAsync(TbDrugUnit);
    userDrugs.forEach((drug: TbUserDrug, index: number) => {
      let dto: DrugShowModelDto = new DrugShowModelDto();
      dto.Id = drug.id;
      dto.Name = drugs.find((x, i) => {
        return x.id === drug.DrugID
      }).DrugName;
      let drugAndType = drugAndTypes.find((x, i) => {
        return x.UserDrugID === drug.id;
      });
      if (drugAndType == undefined) {
        return;
      }
      dto.DrugType = drugTypes.find((x, i) => {
        return x.id = drugAndType.DrugType
      }).Name;
      dto.RemainingNumber = drug.RemainingNumber;
      dto.DrugUnit = drugUnits.find((x, i) => {
        return x.id == drug.UnitID
      }).UnitName;
      dto.ExpirationDate = drug.ExpirationTime;
      dto.IconPath = drug.IconPath;
      dto.Stage = drug.ExpirationTime.getTime() < new Date().getTime() ? FilterRange.已过期 : FilterRange.有效期内;
      dto.CreateTime = drug.CreateTime;
      result.push(dto);
    });
    return result;
  }

  /**
   * 用户删除药品
   * @param data
   * @returns
   */
  public static async DeleteDrugAsync(dataID: number): Promise<string> {
    //删除药品和药品类型的数据
    let datas: TbUserDrug[] = await DBUtil.QueryAsync(TbUserDrug, async (x) => {
      return await x.equalTo("id", dataID)
    })
    if (datas.length == 0) {
      return "药品不存在或已经删除"
    }
    let drugAndType: TbDrugAndType[] = await DBUtil.QueryAsync(TbDrugAndType, async (x) => {
      return await x.equalTo("UserDrugID", datas[0].id);
    })
    DBUtil.DeleteAsync(TbDrugAndType, drugAndType);
    //删除药品数据
    DBUtil.DeleteAsync(TbUserDrug, datas);
    return "成功删除"
  }
}